<?php
/**
 * @version sofortueberweisung.de 5 - $Date: 2012-04-13 17:15:03 +0200 (Fri, 13 Apr 2012) $
 * @author Payment Network AG (integration@payment-network.com)
 * @link http://www.payment-network.com/
 *
 * @copyright 2011 Payment Network AG
 *
 * @link http://www.xt-commerce.com
 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 *
 ***********************************************************************************
 * this file contains code based on:
 * (c) 2000 - 2001 The Exchange Project
 * (c) 2001 - 2003 osCommerce, Open Source E-Commerce Solutions
 * (c) 2003	 nextcommerce (account_history_info.php,v 1.17 2003/08/17); www.nextcommerce.org
 * (c) 2003 - 2006 XT-Commerce
 * Released under the GNU General Public License
 ***********************************************************************************
 *
 * $Id: sofort_sofortrechnung.php 3796 2012-04-13 15:15:03Z rotsch $
 *
 */

/** API VERSION CONSTANT **/
define('API_SR_VERSION', 'pn_xtc_5.1.0');

require_once(DIR_FS_CATALOG.'callback/sofort/sofort.php');
require_once(DIR_FS_CATALOG.'callback/sofort/library/sofortLib.php');

class sofort_sofortrechnung extends sofort{

	var $code, $title, $description, $enabled, $invoice, $paymentMethod;

	function sofort_sofortrechnung() {
		global $order;

		$this->checkExistingSofortConstants('sr');

		$this->code = 'sofort_sofortrechnung';
		$this->title = MODULE_PAYMENT_SOFORT_SR_TEXT_TITLE ;
		$this->title_extern = MODULE_PAYMENT_SOFORT_SOFORTRECHNUNG_TEXT_TITLE;
		$this->paymentMethod = 'SR';

		if (MODULE_PAYMENT_SOFORT_SR_RECOMMENDED_PAYMENT == 'True') {
			$this->title_extern .= ' ' . MODULE_PAYMENT_SOFORT_SR_RECOMMENDED_PAYMENT_TEXT;
		}

		$this->description = MODULE_PAYMENT_SOFORT_SR_TEXT_DESCRIPTION;
		$this->sort_order = MODULE_PAYMENT_SOFORT_SR_SORT_ORDER;
		$this->enabled = ((MODULE_PAYMENT_SOFORT_SR_STATUS == 'True') ? true : false);
		$this->tmpOrders = true;
		$this->tmpStatus = MODULE_PAYMENT_SOFORT_SR_TMP_STATUS_ID;
		if (is_object($order)) {
			$this->update_status();
		}
		$this->defaultCurrency = DEFAULT_CURRENCY;

		$this->invoice = new PnagInvoice(MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY, '');
		$this->invoice->setVersion(API_SR_VERSION);

		$this->form_action_url = "";

		//for compatibility with previous installed versions
		$this->installSofortOrdersTable();
		$this->installSofortOrdersNotificationTable();
	}


	function selection () {

		$title = '';

		switch (MODULE_PAYMENT_SOFORT_MULTIPAY_IMAGE) {
			case 'Logo & Text':
				$title = $this->setImageText('logo_155x50.png', MODULE_PAYMENT_SOFORT_MULTIPAY_SR_CHECKOUT_TEXT);
				break;
			case 'Infographic':
				$title = $this->setImageText('banner_300x100.png', '');
				break;
		}

		$cost = '';
		if(array_key_exists('ot_sofort',  $GLOBALS)) {
			$cost = $GLOBALS['ot_sofort']->get_percent($this->code, 'price');
		}

		$conditionsChecked = false;
		if($_SESSION['sofort_conditions_sr'] == 'sofort_conditions_sr') {
			$conditionsChecked = true;
		}

		$fields = array(
			array('title' => MODULE_PAYMENT_SOFORT_SR_CHECKOUT_CONDITIONS,
					'field' => xtc_draw_checkbox_field('sofort_conditions_sr', 'sofort_conditions_sr', $conditionsChecked))
			);

		return array('id' => $this->code , 'module' => $this->title_extern , 'fields' => $fields, 'description' => $title, 'module_cost' => $cost	);
	}


	function setImageText($image, $text) {
		switch ($_SESSION['language']){
			case 'german': $image = 'https://images.sofort.com/de/sr/'.$image; break;
			case 'dutch':  $image = 'https://images.sofort.com/nl/sr/'.$image; break;
			case 'polish': $image = 'https://images.sofort.com/pl/sr/'.$image; break;
			//english is fallback for unknown langs
			case 'english':
			default:	   $image = 'https://images.sofort.com/en/sr/'.$image; break;
		}

		$image = xtc_image($image, MODULE_PAYMENT_SOFORT_SR_TEXT_DESCRIPTION_CHECKOUT_PAYMENT_IMAGEALT);
		$title = MODULE_PAYMENT_SOFORT_SR_TEXT_DESCRIPTION_CHECKOUT_PAYMENT_IMAGE;
		$title = str_replace('{{image}}', $image, $title);
		$title = str_replace('{{text}}', $text, $title);
		return $title;
	}


	function pre_confirmation_check ($vars = '') {

		parent::pre_confirmation_check ($vars);

		//in CommerceSEO check is sometimes done with Ajax
		if (isset ($_POST['xajax']) && $_POST['xajax'] == 'updatePaymentModule' ) {
			$data_arr = $vars;
			if (!$data_arr['sofort_conditions_sr'] == 'sofort_conditions_sr') {
				unset($_SESSION['sofort_conditions_sr']);
			}
			$is_ajax = true;
		} else {
			array_walk($_POST, 'maskSpecialChars');
			$data_arr = $_POST;
		}

		if ($data_arr['sofort_conditions_sr']) {
			$_SESSION['sofort_conditions_sr'] = $data_arr['sofort_conditions_sr'];
		}

		if ($data_arr['sofort_conditions_sr'] != 'sofort_conditions_sr' && $_SESSION['sofort_conditions_sr'] != 'sofort_conditions_sr') {
			if ($is_ajax) {
				$payment_error_return = 'payment_error='.$this->code.'&error='.urlencode(MODULE_PAYMENT_SOFORT_MULTIPAY_XML_FAULT_10002);
				$_SESSION['checkout_payment_error'] = $payment_error_return;
			} else {
				$payment_error_return = 'payment_error='.$this->code.'&error_codes=10002';
				xtc_redirect(xtc_href_link(FILENAME_CHECKOUT_PAYMENT, $payment_error_return, 'SSL', true, false));
			}
		}

		return false;
	}


	function payment_action () {
		global $order, $insert_id, $shipping_modules, $order_totals, $currencies, $shopEncoding; //$xtPrice

		if ($_SESSION['customers_status']['customers_status_name'] != TEXT_CUSTOMER_GUEST && $_SESSION['customers_status']['customers_status_name'] != NULL) $customer_id = $_SESSION['customer_id'];
		else $customer_id = '';

		$order_id = $insert_id;
		$_SESSION['cart_pn_sofortueberweisung_ID'] = $_SESSION['cart']->cartID . '-' . $insert_id;

		// Fix for XTC Bug
		// $order->info['total'] is in 'before_process' String without Tax, after email it is TEXT with currency
		// so it has to be set here
		if ($_SESSION['customers_status']['customers_status_show_price_tax'] == 0 && $_SESSION['customers_status']['customers_status_add_tax_ot'] == 1) {
			$total = $order->info['total'] + $order->info['tax'];
		} else {
			$total = $order->info['total'];
		}

		$currency = $_SESSION['currency'];

		$reason_1 = str_replace('{{order_id}}', $order_id, MODULE_PAYMENT_SOFORT_MULTIPAY_REASON_1);
		$reason_1 = str_replace('{{customer_id}}', $customer_id, $reason_1);
		$reason_1 = substr($reason_1, 0, 27);

		$reason_2 = str_replace('{{order_id}}', $order_id, MODULE_PAYMENT_SOFORT_MULTIPAY_TEXT_REASON_2);
		$reason_2 = str_replace('{{customer_id}}', $customer_id, $reason_2);
		$reason_2 = str_replace('{{order_date}}', strftime(DATE_FORMAT_SHORT), $reason_2);
		$reason_2 = str_replace('{{customer_name}}', $order->customer['firstname'] . ' ' . $order->customer['lastname'], $reason_2);
		$reason_2 = str_replace('{{customer_company}}', $order->customer['company'], $reason_2);
		$reason_2 = str_replace('{{customer_email}}', $order->customer['email_address'], $reason_2);
		$reason_2 = substr($reason_2, 0, 27);

		$user_variable_0 = $order_id;
		$user_variable_1 = $customer_id;

		$session = session_name() . '=' . session_id();

		if (ENABLE_SSL == true)
			$server = HTTPS_SERVER;
		else
			$server = HTTP_SERVER;

		// success return url:
		$success_url = $server . DIR_WS_CATALOG . FILENAME_CHECKOUT_PROCESS . '?' . $session;
		// cancel return url:
		$cancel_url = $server . DIR_WS_CATALOG . FILENAME_CHECKOUT_PAYMENT . '?payment_error='.$this->code.'&' . $session;
		// notification url:
		$notification_url = $server . DIR_WS_CATALOG . 'callback/sofort/callback.php'; //deprecated

		$user_variable_2 = $_SESSION['cart']->cartID;

		$this->invoice->setCurrency($currency);  //others than EUR will currently not be accepted by API!
		$this->invoice->setReason(helperFunctions::convertEncoding($reason_1,3), helperFunctions::convertEncoding($reason_2,3));
		$this->invoice->setSuccessUrl(helperFunctions::convertEncoding($success_url,3));
		$this->invoice->setAbortUrl(helperFunctions::convertEncoding($cancel_url,3));
		$this->invoice->setTimeoutUrl(helperFunctions::convertEncoding($cancel_url,3));
		$this->invoice->setNotificationUrl(helperFunctions::convertEncoding($notification_url,3));
		$this->invoice->addUserVariable(helperFunctions::convertEncoding($user_variable_0,3));
		$this->invoice->addUserVariable(helperFunctions::convertEncoding($user_variable_1,3));
		$this->invoice->addUserVariable(helperFunctions::convertEncoding($user_variable_2,3));
		$this->invoice->setEmailCustomer(helperFunctions::convertEncoding($order->customer['email_address'],3));
		$this->invoice->setPhoneNumberCustomer($order->customer['telephone']);

		$this->invoice->setSofortrechnung();
		$this->invoice->setCustomerId(helperFunctions::convertEncoding($customer_id,3));
		$this->invoice->setOrderId(helperFunctions::convertEncoding($order_id,3));

		//split address into street and number at last dot or space
		//could get rather messy for foreign addresses, but we only deal with german customers right now
		if(!preg_match('#(.+)[ .](.+)#i', trim($order->billing['street_address']), $billing)) {
			$billing = array();
			$billing[1] = trim($order->billing['street_address']);
			$billing[2] = '';
		}
		if(!preg_match('#(.+)[ .](.+)#i', trim($order->delivery['street_address']), $delivery)) {
			$delivery = array();
			$delivery[1] = trim($order->delivery['street_address']);
			$delivery[2] = '';
		}

		//get billing-salutation: 1=company, 2=masculine, 3=feminine
		$company = trim($order->billing['company']);
		if ($company) {
			$billingSalutation = 1;
		}else{
			//xtc_modified-Bug: only $order->customer has a gender
			$billingSalutation = $this->_getGenderFromAddressBook($order->billing['firstname'], $order->billing['lastname'], $order->billing['company'], $order->billing['street_address'],
					$order->billing['postcode'], $order->billing['city'], $order->billing['country_id'], $order->billing['zone_id']);
		}
		
		//get deliver-salutation: 2=masculine, 3=feminine
		$deliverSalutation = $this->_getGenderFromAddressBook($order->delivery['firstname'], $order->delivery['lastname'], $order->delivery['company'], $order->delivery['street_address'],
				$order->delivery['postcode'], $order->delivery['city'], $order->delivery['country_id'], $order->delivery['zone_id']);

		$this->invoice->addInvoiceAddress(helperFunctions::convertEncoding($order->billing['firstname'],3), helperFunctions::convertEncoding($order->billing['lastname'],3),
						helperFunctions::convertEncoding($billing[1],3), $billing[2], $order->billing['postcode'], helperFunctions::convertEncoding($order->billing['city'],3), $billingSalutation, $order->billing['country']['iso_code_2']);
		$this->invoice->addShippingAddress(helperFunctions::convertEncoding($order->delivery['firstname'],3), helperFunctions::convertEncoding($order->delivery['lastname'],3),
						helperFunctions::convertEncoding($delivery[1],3), $delivery[2], $order->delivery['postcode'], helperFunctions::convertEncoding($order->delivery['city'],3), $deliverSalutation, $order->delivery['country']['iso_code_2']);

		//make EVERY item (article, postage, credit memo, etc.) unique with an own $item_id ==> md5 (order_id | product_id);
		//needed if article-changes made at PNAG-Backend (delete article or quantity of article) to find out in the shop which article has been changed
		$paymentIdString = '';
		foreach($order->products as $product) {
			$paymentIdString = $order_id.'|'.$product['id'];
			//get attributes and add as description to item
			$description = '';
			if ((isset ($product['attributes'])) && (sizeof($product['attributes']) > 0)) {
				foreach ($product['attributes'] as $attribute) {
						$description .= $attribute['option'] . ": " . $attribute['value'] . "\n";
				}
				$description = trim($description); //remove last \n
			}

			//$this->invoice->addItemToInvoice(md5($paymentIdString), helperFunctions::convertEncoding($product['model'],3), helperFunctions::convertEncoding($product['name'],3), $product['price'] * $order->info['currency_value'], 0, helperFunctions::convertEncoding($description,3), $product['qty'], $product['tax']);
			$this->invoice->addItemToInvoice(md5($paymentIdString), helperFunctions::convertEncoding($product['model'],3), helperFunctions::convertEncoding($product['name'],3), $product['price'], 0, helperFunctions::convertEncoding($description,3), $product['qty'], $product['tax']);
		}

		//add shipping to cart
		list ($shippingModule, $shippingMethod) = explode('_', $_SESSION['shipping']['id']); //e.g. "dp_dp" or "freeamount_freeamount"
		if($shippingModule) { //should always be set!
			global $$shippingModule;
			$shippingAmount = $order->info['shipping_cost'] * $order->info['currency_value'];
			$shippingObject = $$shippingModule;
			$shippingTaxClass = xtc_get_tax_rate($shippingObject->tax_class);
			$shippingTaxClass = $this->_checkNullPercentTax($shippingTaxClass);
			$shippingIdString = 'ot_shipping|'.$order_id;
			$this->invoice->addItemToInvoice(md5($shippingIdString), '', helperFunctions::convertEncoding(html_entity_decode($order->info['shipping_method'],ENT_QUOTES,helperFunctions::getIniValue('shopEncoding')),3), $shippingAmount, 1, '', 1, (double)$shippingTaxClass);
		}

		//check optional price-modificators like ot_sofort, loworderfee, discount
		if(is_array($order_totals) ) {
			foreach($order_totals as $total_module) {
				//notice: tax is always set to 19% here!
				if($total_module['code'] == 'ot_sofort') {
					$md5String = 'ot_sofort|'.$order_id.mt_rand();
					$tax = xtc_get_tax_rate(MODULE_ORDER_TOTAL_SOFORT_TAX_CLASS);
					$tax = $this->_checkNullPercentTax($tax);
					//$amount = $total_module['value'] * $order->info['currency_value']; //bug in xtc: currency-value is not used by ot_modules although its written in this modules
					$this->invoice->addItemToInvoice(md5($md5String), '',helperFunctions::convertEncoding(html_entity_decode($total_module['title'],ENT_QUOTES,HelperFunctions::getIniValue('shopEncoding')),3), $total_module['value'], 0, '', 1, $tax);
				}
				if($total_module['code'] == 'ot_loworderfee') {
					$md5String = 'ot_loworderfee|'.$order_id.mt_rand();
					$tax = xtc_get_tax_rate(MODULE_ORDER_TOTAL_LOWORDERFEE_TAX_CLASS);
					$tax = $this->_checkNullPercentTax($tax);
					//$amount = $total_module['value'] * $order->info['currency_value'];
					$this->invoice->addItemToInvoice(md5($md5String), '',helperFunctions::convertEncoding(html_entity_decode($total_module['title'],ENT_QUOTES,HelperFunctions::getIniValue('shopEncoding')),3), $total_module['value'], 0, '', 1, $tax);
				}
				if($total_module['code'] == 'ot_discount') {
					$md5String = 'ot_discount|'.$order_id.mt_rand();
					$tax = $this->_checkNullPercentTax(0); //set the highest article-tax to this position
					$amountValue = ($total_module['value'] > 0) ? ($total_module['value'] * -1) : $total_module['value'];
					//$amount = $total_module['value'] * $order->info['currency_value'];
					$this->invoice->addItemToInvoice(md5($md5String), '',helperFunctions::convertEncoding(html_entity_decode($total_module['title'],ENT_QUOTES,HelperFunctions::getIniValue('shopEncoding')),3), $amountValue, 0, '', 1, $tax);
				}
				if($total_module['code'] == 'ot_gv') {
					$md5String = 'ot_gv|'.$order_id.mt_rand();
					$tax = xtc_get_tax_rate(MODULE_ORDER_TOTAL_GV_TAX_CLASS);
					$tax = $this->_checkNullPercentTax($tax);
					$amountValue = ($total_module['value'] > 0) ? ($total_module['value'] * -1) : $total_module['value'];
					//$amount = $total_module['value'] * $order->info['currency_value'];
					$this->invoice->addItemToInvoice(md5($md5String), '',helperFunctions::convertEncoding(html_entity_decode($total_module['title'],ENT_QUOTES,HelperFunctions::getIniValue('shopEncoding')),3), $amountValue, 0, '', 1, $tax);
				}
				if($total_module['code'] == 'ot_coupon') {
					$md5String = 'ot_coupon|'.$order_id.mt_rand();
					$tax = xtc_get_tax_rate(MODULE_ORDER_TOTAL_COUPON_TAX_CLASS);
					$tax = $this->_checkNullPercentTax($tax);
					$amountValue = ($total_module['value'] > 0) ? ($total_module['value'] * -1) : $total_module['value'];
					//$amount = $total_module['value'] * $order->info['currency_value'];
					$this->invoice->addItemToInvoice(md5($md5String), '',helperFunctions::convertEncoding(html_entity_decode($total_module['title'],ENT_QUOTES,HelperFunctions::getIniValue('shopEncoding')),3), $amountValue, 0, '', 1, $tax);
				}
			}
		}

		//check shopTotal against the invoiceclassTotal
		$shopTotal = number_format($total, 2, '.','');
		$invoiceTotal = $this->invoice->getAmount();
		if (!$this->_checkShopTotalVsInvoiceTotal ($shopTotal, $invoiceTotal) ) {
			$this->invoice->log('ShopTotal is not near InvoiceTotal! OrderID: '.$order_id.'. Are you using price-modification-tools 
								which are not supported by this "Rechnung bei sofort"-module? Was the tax-rate of all affected articles, 
								shipping options and other positions set correctly? Did you set the currency-exchange-rate correctly?');
			xtc_redirect($cancel_url);
		}
		
		//send all data to the API and place an order at pnag if no errors
		$checkoutResult = $this->invoice->checkout();

		if($this->invoice->isError()) {
			$this->_handleErrors($this->invoice->getErrors(), $cancel_url);
		} else {
			$url = $this->invoice->getPaymentUrl();
			$tid = $this->invoice->getTransactionId();

			// Additionally update status
			$time = strftime(' %Y-%m-%d %H:%M:%S');
			$sql_data_array = array(
				'orders_id' => (int) $order_id,
				'orders_status_id' => MODULE_PAYMENT_SOFORT_SR_TMP_STATUS_ID ,
				'date_added' => 'sqlcommand:now()' ,
			 	'customer_notified' => HelperFunctions::getIniValue('sofortCustomerNotified'),
				'comments' => MODULE_PAYMENT_SOFORT_SR_TMP_COMMENT.' '.MODULE_PAYMENT_SOFORT_SR_TRANSLATE_TIME.': '.$time);
			xtc_db_query(helperFunctions::getEscapedInsertInto(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array));
			xtc_db_query("UPDATE ".helperFunctions::escapeSql(TABLE_ORDERS)." SET orders_ident_key='".helperFunctions::escapeSql($tid)."' WHERE orders_id='".helperFunctions::escapeSql($order_id)."'");
			
			$this->_saveOrderInSofortTables($order_id);
			
			$_SESSION['transactionId'] = $tid;
			$_SESSION['sofortrechnung_shoptotal'] = $shopTotal;
			
			$_SESSION['sofort_payment_url'] = $url;
			$_SESSION['sofort_payment_method'] = $this->code;
			xtc_redirect($server . DIR_WS_CATALOG . 'callback/sofort/processSofortPayment.php');
		}
	}


	function after_process() {
		global $insert_id;

		//if we reached this point the mail is already sent so set customer_notified flag
		if(SEND_EMAILS == 'true' && is_int($insert_id)) {
			xtc_db_query("UPDATE ".helperFunctions::escapeSql(TABLE_ORDERS_STATUS_HISTORY)." SET customer_notified='1' WHERE orders_id='".helperFunctions::escapeSql($insert_id)."' ORDER BY orders_status_history_id DESC LIMIT 1");
		}

		//delete sofort-vars in the session and set customer notified if user got an order-email
		parent::after_process();
	}


	function _saveOrderInSofortTables($insert_id){
		if($insert_id){
			$sql = 'SELECT orders_ident_key FROM '.TABLE_ORDERS.' WHERE orders_id = '.$insert_id.'';
			$resultSet = xtc_db_query($sql);
			$result = xtc_db_fetch_array($resultSet);
			if (empty($result['orders_ident_key'])) {
				return false;
			}
			$transactionId = $result['orders_ident_key'];
			$invoice = new PnagInvoice(MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY, $transactionId);
			
			$sofortOrdersId = helperFunctions::insertSofortOrder($insert_id, '', $invoice);
			/*
			 * activate following line, if the first historycomment should also be inserted into sofort-notifications-table
			 * if activated, the buyer-comment ("F�gen Sie hier Ihre Anmerkungen zu dieser Bestellung ein") can also be included here */
			//helperFunctions::insertSofortOrdersNotification($sofortOrdersId, $invoice, SOFORT_GENERAL_SELECTED_PENDING_SR, SOFORT_GENERAL_SELECTED_PENDING_SR);
			return true;
		}else{
			//nothing inserted into sofort-tables
			return false;
		}
	}


	function install() {
		$sofortStatuses = $this->insertAndReturnSofortStatus(true);
		$tempStatus = 		(isset($sofortStatuses['temp']) 	&& !empty($sofortStatuses['temp']))		? $sofortStatuses['temp'] : '';
		$confirmedStatus = 	(isset($sofortStatuses['confirmed'])&& !empty($sofortStatuses['confirmed']))? $sofortStatuses['confirmed'] : '';
		$canceledStatus = 	(isset($sofortStatuses['canceled']) && !empty($sofortStatuses['canceled']))	? $sofortStatuses['canceled'] : '';

		xtc_db_query("INSERT INTO " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, date_added) values ('MODULE_PAYMENT_SOFORT_SR_STATUS', 'True', '6', '1', 'xtc_cfg_select_option(array(\'True\', \'False\'), ', now())");
		xtc_db_query("INSERT INTO " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, date_added) values ('MODULE_PAYMENT_SOFORT_SR_SORT_ORDER', '0', '6', '20', now())");
		xtc_db_query("INSERT INTO " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, date_added) values ('MODULE_PAYMENT_SOFORT_SR_RECOMMENDED_PAYMENT', 'False', '6', '1', 'xtc_cfg_select_option(array(\'True\', \'False\'), ', now())");
		xtc_db_query("INSERT INTO " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, use_function, date_added) values ('MODULE_PAYMENT_SOFORT_SR_ORDER_STATUS_ID', '".helperFunctions::escapeSql($confirmedStatus)."',  '6', '10', 'xtc_cfg_pull_down_order_statuses(', 'xtc_get_order_status_name', now())");
		xtc_db_query("INSERT INTO " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, use_function, date_added) values ('MODULE_PAYMENT_SOFORT_SR_TMP_STATUS_ID', '".helperFunctions::escapeSql($tempStatus)."', '6', '8', 'xtc_cfg_pull_down_order_statuses(', 'xtc_get_order_status_name', now())");
		xtc_db_query("INSERT INTO " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, set_function, use_function, date_added) values ('MODULE_PAYMENT_SOFORT_SR_CANCEL_STATUS_ID', '".helperFunctions::escapeSql($canceledStatus)."',  '6', '8', 'xtc_cfg_pull_down_order_statuses(', 'xtc_get_order_status_name', now())");
		xtc_db_query("INSERT INTO " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, date_added) values ('MODULE_PAYMENT_SOFORT_SOFORTRECHNUNG_ALLOWED', '', '6', '0', now())");
		xtc_db_query("INSERT INTO " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " ( configuration_key, configuration_value,  configuration_group_id, sort_order, use_function, set_function, date_added) values ('MODULE_PAYMENT_SOFORT_SR_ZONE', '0', '6', '2', 'xtc_get_zone_class_title', 'xtc_cfg_pull_down_zone_classes(', now())");

		/*
		currently done in constructor
		$this->installSofortOrdersTable();
		$this->installSofortOrdersNotificationTable();
		*/

		//install shared keys, that are used by all/most multipay-modules
		parent::install();
	}


	function remove() {
		xtc_db_query("delete from " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " where configuration_key LIKE 'MODULE_PAYMENT_SOFORT_SR%'");
		xtc_db_query("delete from " . helperFunctions::escapeSql(TABLE_CONFIGURATION) . " where configuration_key LIKE 'MODULE_PAYMENT_SOFORT_SOFORTRECHNUNG%'");

		/*	We don't want to delete data, but you could in some cases...
		$this->removeSofortOrdersTable();
		$this->removeSofortOrdersNotificationTable();
		*/

		//if this is the last removing of a multipay-paymentmethod --> we also remove all shared keys, that are used by all/most multipay-modules
		parent::remove();
	}



	function installSofortOrdersTable() {
		$sql = '
			CREATE TABLE IF NOT EXISTS `sofort_orders` (
				`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
				`orders_id` int(11) unsigned NOT NULL,
				`transaction_id` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
				`payment_method` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
				`payment_secret` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
				`date_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
				PRIMARY KEY (`id`)
			)
		';
		xtc_db_query($sql);
	}


	function removeSofortOrdersTable() {
		$sql = 'DROP TABLE `sofort_orders`';
		xtc_db_query($sql);
	}


	function installSofortOrdersNotificationTable() {
		$sql = '
			CREATE TABLE IF NOT EXISTS `sofort_orders_notification` (
				`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
				`sofort_orders_id` int(11) unsigned NOT NULL,
				`items` text COLLATE utf8_unicode_ci NOT NULL,
				`amount` float NOT NULL,
				`customer_comment` text COLLATE utf8_unicode_ci NOT NULL,
				`seller_comment` text COLLATE utf8_unicode_ci NOT NULL,
				`status_id` int(11) unsigned NOT NULL,
				`status` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
				`status_reason` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
				`invoice_status` varchar(32) COLLATE utf8_unicode_ci NOT NULL,
				`invoice_objection` varchar(45) COLLATE utf8_unicode_ci NOT NULL,
				`date_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
				PRIMARY KEY (`id`)
			)
		';
		xtc_db_query($sql);
	}


	function removeSofortOrdersNotificationTable() {
		$sql = 'DROP TABLE `sofort_orders_notification`';
		xtc_db_query($sql);
	}


	function keys() {
		return array('MODULE_PAYMENT_SOFORT_SR_STATUS',
		'MODULE_PAYMENT_SOFORT_MULTIPAY_APIKEY',
		'MODULE_PAYMENT_SOFORT_MULTIPAY_AUTH',
		'MODULE_PAYMENT_SOFORT_SR_RECOMMENDED_PAYMENT',
		'MODULE_PAYMENT_SOFORT_SOFORTRECHNUNG_ALLOWED' ,
		'MODULE_PAYMENT_SOFORT_SR_ZONE' ,
		//'MODULE_PAYMENT_SOFORT_MULTIPAY_IMAGE',
		'MODULE_PAYMENT_SOFORT_SR_TMP_STATUS_ID',
		'MODULE_PAYMENT_SOFORT_SR_ORDER_STATUS_ID',
		'MODULE_PAYMENT_SOFORT_SR_CANCEL_STATUS_ID',
		'MODULE_PAYMENT_SOFORT_MULTIPAY_CANCELED_ORDER_STATUS_ID',
		'MODULE_PAYMENT_SOFORT_SR_SORT_ORDER');
	}


	/**
	 * if there is more than 1% difference this function returns false
	 * @return true/false
	 */
	function _checkShopTotalVsInvoiceTotal ($shopTotal, $invoiceTotal){
		if ($shopTotal < $invoiceTotal) {
			$percent = $shopTotal/$invoiceTotal;
		} else {
			$percent = $invoiceTotal/$shopTotal;
		}

		if ($percent < 0.99) {
			return false;
		} else {
			return true;
		}
	}


	/**
	 * check if given tax == 0 --- if yes: return highest shoparticle tax ELSE given tax - 
	 * tax with 0% is not allowed at pnag-API
	 * @param int/float $taxToCheck
	 */
	function _checkNullPercentTax($taxToCheck){
		if ((int)$taxToCheck == 0){
			return $this->invoice->getHighestShoparticleTax();
		}else{
			return $taxToCheck;
		}
	}
}
?>